package performance;

import java.time.Instant;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author wuwen
 * @since 2024/1/19
 */
public class StreamParallelDemo {
    public static void main(String[] args) {
        // data init
        List<Integer> handle = new ArrayList<>();
        for (int i = 1; i <= 5000; i++) {
            handle.add(i);
        }
        // begin test
        System.out.println("singleLoop() = " + singleCommonLoop(handle) + "ms");
        System.out.println("singleStream() = " + singleStream(handle) + "ms");
        System.out.println("parallelStream() = " + parallelStream(handle) + "ms");
    }

    /**
     * 单线程普通方法
     */
    private static long singleCommonLoop(List<Integer> src) {
        Instant begin = Instant.now();
        List<Integer> dest = new ArrayList<>();
        for (Integer item : src) {
            // 模拟对数据进行拼装操作
            try {
                item += 10;
                Thread.sleep(5);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            // 数据填充
            dest.add(item);
        }
        Instant end = Instant.now();
        return ChronoUnit.MILLIS.between(begin, end);
    }

    /**
     * 单线程stream方法
     */
    private static long singleStream(List<Integer> data) {
        Instant begin = Instant.now();
        data = data.stream().map(item -> {
            try {
                item += 10;
                Thread.sleep(5);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return item;
        }).collect(Collectors.toList());
        Instant end = Instant.now();
        return ChronoUnit.MILLIS.between(begin, end);
    }

    /**
     * 多线程stream方法
     */
    private static long parallelStream(List<Integer> data) {
        Instant begin = Instant.now();
        data = data.parallelStream().map(item -> {
            try {
                item += 10;
                Thread.sleep(5);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return item;
        }).collect(Collectors.toList());
        Instant end = Instant.now();
        return ChronoUnit.MILLIS.between(begin, end);
    }
}
